home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 2007-2009 Pearl Crescent, LLC. All Rights Reserved. */
- /* vim: set sw=2 sts=2 ts=8 et syntax=javascript: */
-
- var gAviaryUpload =
- {
- // If aOpenWithToolID is not zero, image is opened in app after uploading.
- // aInputStream must be an nsIBinaryInputStream.
- UploadStream: function(aContentType, aInputStream, aFileName, aOriginatingURL,
- aProgressMeter, aOpenWithToolID)
- {
- if (!aContentType || !aInputStream)
- {
- throw new Components.Exception("missing parameter",
- Components.results.NS_ERROR_INVALID_ARG);
- }
-
- if (aProgressMeter && aProgressMeter.IsCanceled())
- {
- aProgressMeter.Close(false, null);
- return;
- }
-
- var uploader = new AviaryFileUploader(aContentType, aInputStream, null,
- aFileName, aOriginatingURL,
- aProgressMeter, aOpenWithToolID);
- },
-
- // If aOpenWithToolID is not zero, image is opened in app after uploading.
- UploadByURL: function(aImageURL, aOpenWithToolID)
- {
- if (!aImageURL)
- {
- throw new Components.Exception("missing parameter",
- Components.results.NS_ERROR_INVALID_ARG);
- }
-
- var uploader = new AviaryFileUploader(null, null, aImageURL, null, null,
- null, aOpenWithToolID);
- },
-
- endOfObject: true
- };
-
- // It would be better to nest this within gAviaryUpload.
- function AviaryFileUploader(aContentType, aInputStream, aImageURL, aFileName,
- aOriginatingURL, aProgressMeter, aOpenWithToolID)
- {
- this.init(aContentType, aInputStream, aImageURL, aFileName, aOriginatingURL,
- aProgressMeter, aOpenWithToolID);
- }
-
- AviaryFileUploader.prototype =
- {
- kUploadDestURL: "",
- kFileDetailsURL: "",
- kUploadDestURLSuffix: "/apps/xmlapi/receiver.aspx",
- kFileDetailsURLSuffix: "/creation?fguid=",
- kUploadSource: "upload",
- kUploadAUID: "aviaryframework",
- kUploadAndEditAUID: "aviarysourcefile",
- kMIMEBoundaryPrefix: "--------AVIARY_",
- kEndOfLineStr: "\r\n",
-
- mPearlUtil: null,
- mOpenWithToolID: 0,
- mRequest: null,
- mRequestHasBeenAborted: false,
- mMIMEBoundary: null,
- mProgressMeter: null,
-
- init: function(aContentType, aInputStream, aImageURL, aFileName,
- aOriginatingURL, aProgressMeter, aOpenWithToolID)
- {
- if (!aImageURL && (!aContentType || !aInputStream))
- {
- throw new Components.Exception("missing parameter",
- Components.results.NS_ERROR_INVALID_ARG);
- }
-
- this.mPearlUtil = com.aviary.talon.pearlutil;
- this.mProgressMeter = aProgressMeter;
- this.mOpenWithToolID = aOpenWithToolID;
- this.mMIMEBoundary = this.kMIMEBoundaryPrefix + Math.random();
-
- var serverPrefix = this.mPearlUtil.GetASCIIPref("aviary.serverPrefix");
- if (serverPrefix)
- {
- this.kUploadDestURL = serverPrefix + this.kUploadDestURLSuffix;
- this.kFileDetailsURL = serverPrefix + this.kFileDetailsURLSuffix;
- }
- // this.kUploadDestURL = "http://quartz/dist/aviary/upload/";
-
- if (aProgressMeter)
- {
- var str = this.mPearlUtil.GetLocalizedString("SAVING_TO_ROOKERY");
- aProgressMeter.SetLabel(str);
-
- var self = this;
- aProgressMeter.SetCancelFunction(function() { self.OnCancel(); });
- }
-
- if (!aImageURL)
- {
- if (!aFileName)
- {
- // Use default file name. Determine extension based on content type.
- var fileExt = "";
- if ("image/png" == aContentType)
- fileExt = ".png";
- else if ("image/jpg" == aContentType)
- fileExt = ".jpg";
- else if ("image/gif" == aContentType)
- fileExt = ".gif";
-
- aFileName = this.mPearlUtil
- .GetLocalizedString("SUGGESTED_FILE_PREFIX") + fileExt;
- }
-
- if (aProgressMeter)
- aProgressMeter.SetName(aFileName);
- }
-
- // Create and initialize request.
- this.mRequest = new XMLHttpRequest();
-
- var self = this;
- this.mRequest.onload = function() { self.onLoad(self); }
- this.mRequest.onerror = function() { self.onError(self); }
- this.mRequest.onuploadprogress =
- function(aEvent) { self.onUploadProgress(self, aEvent); }
-
- this.mRequest.open("POST", this.kUploadDestURL, true);
- com.aviary.talon.request.
- EnsureCookiesWillBeSent(this.mRequest.channel, null);
- this.mRequest.setRequestHeader("Content-type",
- "multipart/form-data; boundary=" + this.mMIMEBoundary);
- this.mRequest.overrideMimeType("application/xml");
-
- // Arrange to send a file upload form post.
- const kMSCID = "@mozilla.org/io/multiplex-input-stream;1";
- var multiStream = Components.classes[kMSCID]
- .createInstance(Components.interfaces.nsIMultiplexInputStream);
- var s = this.createInputStringBodyPart("source", this.kUploadSource);
- var auid = (0 != this.mOpenWithToolID) ? this.kUploadAndEditAUID
- : this.kUploadAUID;
- s += this.createInputStringBodyPart("auid", auid);
- multiStream.appendStream(this.createStringStream(s));
-
- var endOfMIMESuffix = "";
- if (aImageURL)
- {
- // To cause an error, use s += on next line.
- s = this.createInputStringBodyPart("url", aImageURL);
- multiStream.appendStream(this.createStringStream(s));
- }
- else
- {
- if (aOriginatingURL)
- {
- s = this.createInputStringBodyPart("originalurl", aOriginatingURL);
- multiStream.appendStream(this.createStringStream(s));
- }
-
- var filePrefix = "--" + this.mMIMEBoundary + this.kEndOfLineStr
- + "Content-Disposition: form-data; name=\"file\"; "
- + "filename=\"" + aFileName + "\"" + this.kEndOfLineStr
- + "Content-type: " + aContentType + this.kEndOfLineStr
- + this.kEndOfLineStr;
- multiStream.appendStream(this.createStringStream(filePrefix));
-
- /*
- * Ensure that the image stream is seekable (required by NoScript and
- * possibly by Necko).
- */
- var storageStream = Components.classes["@mozilla.org/storagestream;1"]
- .createInstance(Components.interfaces.nsIStorageStream);
- storageStream.init(32768, -1, null);
- var outputStream = storageStream.getOutputStream(0);
- const kMaxBlockSize = 65536;
- var remaining = aInputStream.available();
- while (remaining > 0)
- {
- var count = (remaining > kMaxBlockSize) ? kMaxBlockSize : remaining;
- var b = aInputStream.readBytes(count);
- outputStream.write(b, count);
- remaining -= count;
- }
- outputStream.close();
- multiStream.appendStream(storageStream.newInputStream(0));
-
- endOfMIMESuffix += this.kEndOfLineStr;
- }
-
- endOfMIMESuffix += "--" + this.mMIMEBoundary + this.kEndOfLineStr;
- multiStream.appendStream(this.createStringStream(endOfMIMESuffix));
- this.mRequest.send(multiStream);
- },
-
- onUploadProgress: function(aThisObj, aEvent)
- {
- var percentDone = Math.floor(100 * (aEvent.position / aEvent.totalSize));
- if (percentDone > 100)
- percentDone = 100; // TODO: position exceeds totalSize; FF bug??
- // dump("onUploadProgress: " + percentDone + "% of " + aEvent.totalSize + "\n");
-
- if (aThisObj.mProgressMeter)
- aThisObj.mProgressMeter.SetValue(percentDone);
- },
-
- onLoad: function(aThisObj)
- {
- if (aThisObj.mRequestHasBeenAborted)
- return;
-
- if (aThisObj.mProgressMeter)
- aThisObj.mProgressMeter.SetIsCancelable(false); // Too late to cancel.
-
- var succeeded = false;
- try {
- const knsIHttpChannel = Components.interfaces.nsIHttpChannel;
- var channel = aThisObj.mRequest.channel.QueryInterface(knsIHttpChannel);
- succeeded = channel.requestSucceeded;
- } catch(e) { dump("onLoad: " + e + "\n"); }
-
- // dump("response text:\n" + aThisObj.mRequest.responseText + "\n");
- var fguid = null;
- if (succeeded)
- {
- succeeded = false;
- var responseNode = aThisObj.getResponseNode(aThisObj.mRequest);
- if (responseNode)
- {
- var fileNode = aThisObj.mPearlUtil
- .PearlGetFirstElementByTagName(responseNode, "file");
- if (fileNode)
- {
- fguid = aThisObj.mPearlUtil.GetFirstChildText(fileNode, "fileguid");
- succeeded = (fguid != null && fguid.length > 0);
- }
- }
- }
-
- if (!succeeded)
- {
- aThisObj.onError(aThisObj);
- return;
- }
-
- if (aThisObj.mProgressMeter)
- {
- aThisObj.mProgressMeter.SetValue(100);
- aThisObj.mProgressMeter.Close(true, "IMAGE_SAVED"); // fade out
- }
-
- if (0 != aThisObj.mOpenWithToolID)
- {
- gAviaryMain.LaunchAppByToolID(aThisObj.mOpenWithToolID, fguid,
- null, null);
- }
- else
- {
- var detailsURL = this.kFileDetailsURL + encodeURIComponent(fguid);
- gAviaryMain.OpenInNewTab(detailsURL, null);
- }
- },
-
- onError: function(aThisObj)
- {
- if (aThisObj.mProgressMeter)
- aThisObj.mProgressMeter.Close(false, null); // close immediately
-
- if (aThisObj.mRequestHasBeenAborted) // Suppress errors if canceled.
- return;
-
- // If possible, get detailed information from <failedfiles> within response.
- var errMsg;
- var responseNode = aThisObj.getResponseNode(aThisObj.mRequest);
- if (responseNode)
- {
- var node = aThisObj.mPearlUtil
- .PearlGetFirstElementByTagName(responseNode, "failedfile");
- if (node)
- {
- errMsg = aThisObj.mPearlUtil.GetNodeText(node);
- if (!errMsg)
- errMsg = node.getAttribute("reason");
- }
- }
-
- // TODO: fit this error message within a caller-provider message.
- if (!errMsg)
- errMsg = "Upload failed."; // TODO: L10n
- aThisObj.mPearlUtil.Alert(window, errMsg);
- },
-
- OnCancel: function()
- {
- this.mRequestHasBeenAborted = true;
-
- if (this.mProgressMeter)
- {
- this.mProgressMeter.Close(false, null); // close immediately
- this.mProgressMeter = null;
- }
-
- if (this.mRequest)
- this.mRequest.abort();
- },
-
- getResponseNode: function(aRequest)
- {
- var responseNode = null;
- if (aRequest && aRequest.responseXML)
- {
- var responseDoc = aRequest.responseXML;
- if (responseDoc && responseDoc.firstChild &&
- responseDoc.firstChild.nodeName == "response")
- {
- responseNode = responseDoc.firstChild;
- }
- }
-
- return responseNode;
- },
-
- createStringStream: function(aStr)
- {
- if (!aStr)
- return null;
-
- const kSISCID = "@mozilla.org/io/string-input-stream;1";
- var strStream = Components.classes[kSISCID]
- .createInstance(Components.interfaces.nsIStringInputStream);
- strStream.setData(aStr, aStr.length);
- return strStream;
- },
-
- createInputStringBodyPart: function(aName, aValue)
- {
- if (!aName || !aValue)
- return "";
-
- var s = "--" + this.mMIMEBoundary + this.kEndOfLineStr
- + "Content-Disposition: form-data; name=\"" + aName + "\""
- + this.kEndOfLineStr + this.kEndOfLineStr;
- s += aValue + this.kEndOfLineStr;
- return s;
- },
-
- endOfObject: true
- }
-
-